package com.sapitest.utils.redis;

import com.sapitest.keywords.JSONOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;

/**
 * Redis命令类，常用的redis命令，可扩展，包括key,list,sort,sortedset,hash,string
 * 扩展命令的入参格式必须是String[]，并以字符串形式返回结果，例如 String command(String[] arg)
 * @date 2019-04-20
 * @author Liuxu
 * @version 1.0.1
 * @since jdk1.8
 */
@SuppressWarnings("unused")
public class Commands {
    private static final Logger logger = LoggerFactory.getLogger(Commands.class);
    private Jedis jedis;

    Commands(Jedis jedis) {
        this.jedis = jedis;
    }

    /**
     * 检查入参的个数是否合法
     * @param arg   参数字符串数组
     * @param size  期望的参数个数
     * @return boolean
     */
    private boolean checkArg(String[] arg, int size) {
        if(!(arg.length == size)) {
            logger.error("入参个数不正确，未执行Redis命令");
        }
        return arg.length == size;
    }

    /**
     * hdel key field
     * Hash表命令 hdel，删除哈希表 key 中的一个指定域，不存在的域将被忽略
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String hdel(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.hdel(arg[0], arg[1]));
            logger.info("执行Redis命令：[hdel " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * hget key field
     * Hash表命令 hget，返回哈希表 key 中给定域 field 的值
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String hget(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = jedis.hget(arg[0], arg[1]);
            logger.info("执行Redis命令：[hget " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * hexists key field
     * Hash表命令 hexists，查看哈希表 key 中，给定域 field 是否存在
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String hexists(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.hexists(arg[0], arg[1]));
            logger.info("执行Redis命令：[hexists " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * hgetall key
     * Hash表命令 hgetall，返回哈希表 key 中，所有的域和值
     * 在返回值里，紧跟每个域名(field name)之后是域的值(value)，所以返回值的长度是哈希表大小的两倍
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String hgetall(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = JSONOperation.parseObjectString(jedis.hgetAll(arg[0]));
            logger.info("执行Redis命令：[hgetAll " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * hincrby key field increment
     * Hash表命令 hincrby，为哈希表 key 中的域 field 的值加上增量 increment
     * 增量也可以为负数，相当于对给定域进行减法操作
     * 如果 key 不存在，一个新的哈希表被创建并执行 HINCRBY 命令
     * 如果域 field 不存在，那么在执行命令前，域的值被初始化为 0
     * 对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误
     * 本操作的值被限制在 64 位(bit)有符号数字表示之内
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String hincrby(String[] arg) {
        if (checkArg(arg, 3)) {
            String res = String.valueOf(jedis.hincrBy(arg[0], arg[1], Long.valueOf(arg[2])));
            logger.info("执行Redis命令：[hincrBy " + arg[0] + " " + arg[1] + " " + arg[2] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * hincrby key field increment
     * Hash表命令 hincrbyfloat，为哈希表 key 中的域 field 加上浮点数增量 increment
     * 如果哈希表中没有域 field ，那么 HINCRBYFLOAT 会先将域 field 的值设为 0 ，然后再执行加法操作。
     * 如果键 key 不存在，那么 HINCRBYFLOAT 会先创建一个哈希表，再创建域 field ，最后再执行加法操作。
     * 当以下任意一个条件发生时，返回一个错误：
     *  ·域 field 的值不是字符串类型(因为 redis 中的数字和浮点数都以字符串的形式保存，所以它们都属于字符串类型）
     *  ·域 field 当前的值或给定的增量 increment 不能解释(parse)为双精度浮点数(double precision floating point number)
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String hincrbyfloat(String[] arg) {
        if (checkArg(arg, 3)) {
            String res = String.valueOf(jedis.hincrByFloat(arg[0], arg[1], Double.valueOf(arg[2])));
            logger.info("执行Redis命令：[hincrByFloat " + arg[0] + " " + arg[1] + " " + arg[2] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * hkeys key
     * Hash表命令 hkeys，返回哈希表 key 中的所有域
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String hkeys(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.hkeys(arg[0]));
            logger.info("执行Redis命令：[hkeys " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * hlen key
     * Hash表命令 hlen，返回哈希表 key 中域的数量
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String hlen(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.hlen(arg[0]));
            logger.info("执行Redis命令：[hlen " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * hset key field value
     * Hash表命令 hset，将哈希表 key 中的域 field 的值设为 value
     * 如果 key 不存在，一个新的哈希表被创建并进行 HSET 操作
     * 如果域 field 已经存在于哈希表中，旧值将被覆盖
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String hset(String[] arg) {
        if (checkArg(arg, 3)) {
            String res = String.valueOf(jedis.hset(arg[0], arg[1], arg[2]));
            logger.info("执行Redis命令：[hset " + arg[0] + " " + arg[1] + " " + arg[2] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * del key
     * 键（key）命令 del，删除给定的一个或key，不存在的 key 会被忽略
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String del(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.del(arg[0]));
            logger.info("执行Redis命令：[del " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * exists key
     * 键（key）命令 exists，检查给定 key 是否存在
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String exists(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.exists(arg[0]));
            logger.info("执行Redis命令：[exists " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * expire key seconds
     * 键（key）命令 expire，为给定 key 设置生存时间，当 key 过期时(生存时间为 0 )，它会被自动删除
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String expire(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.expire(arg[0], Integer.valueOf(arg[1])));
            logger.info("执行Redis命令：[expire " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * expireAt key timestamp
     * 键（key）命令 expireAt，EXPIREAT 的作用和 EXPIRE 类似，都用于为 key 设置生存时间
     * 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String expireat(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.expireAt(arg[0], Long.valueOf(arg[1])));
            logger.info("执行Redis命令：[expireAt " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * sort key
     * 键（key）命令 sort，返回或保存给定列表、集合、有序集合 key 中经过排序的元素
     * 排序默认以数字作为对象，值被解释为双精度浮点数，然后进行比较
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String sort(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.sort(arg[0]));
            logger.info("执行Redis命令：[sort " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * ttl key
     * 键（key）命令 ttl，以秒为单位，返回给定 key 的剩余生存时间(TTL, time to live)
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String ttl(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.ttl(arg[0]));
            logger.info("执行Redis命令：[ttl " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * persist key
     * 键（key）命令 persist，移除给定 key 的生存时间，将这个 key 从『易失的』(带生存时间 key )转换成『持久的』(一个不带生存时间、永不过期的 key )
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String persist(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.persist(arg[0]));
            logger.info("执行Redis命令：[persist " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * llen key
     * 列表（List）命令 llen，返回列表 key 的长度
     * 如果 key 不存在，则 key 被解释为一个空列表，返回 0
     * 如果 key 不是列表类型，返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String llen(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.llen(arg[0]));
            logger.info("执行Redis命令：[llen " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * lindex key index
     * 列表（List）命令 lindex，返回列表 key 中，下标为 index 的元素
     * 下标(index)参数 start 和 stop 都以 0 为底，也就是说，以 0 表示列表的第一个元素，以 1 表示列表的第二个元素，以此类推
     * 你也可以使用负数下标，以 -1 表示列表的最后一个元素， -2 表示列表的倒数第二个元素，以此类推
     * 如果 key 不是列表类型，返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String lindex(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = jedis.lindex(arg[0], Long.valueOf(arg[1]));
            logger.info("执行Redis命令：[lindex " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * lpush key value
     * 列表（List）命令 lpush，将一个 value 插入到列表 key 的表头
     * 下如果 key 不存在，一个空列表会被创建并执行 LPUSH 操作
     * 如果 key 不是列表类型，返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String lpush(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.lpush(arg[0], arg[1]));
            logger.info("执行Redis命令：[lpush " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * lrange key start stop
     * 列表（List）命令 lrange，返回列表 key 中指定区间内的元素，区间以偏移量 start 和 stop 指定
     * 下标(index)参数 start 和 stop 都以 0 为底，也就是说，以 0 表示列表的第一个元素，以 1 表示列表的第二个元素，以此类推
     * 你也可以使用负数下标，以 -1 表示列表的最后一个元素， -2 表示列表的倒数第二个元素，以此类推
     * stop 下标也在 LRANGE 命令的取值范围之内(闭区间)
     * 超出范围的下标
     *  ·超出范围的下标值不会引起错误。
     *  ·如果 start 下标比列表的最大下标 end ( LLEN list 减去 1 )还要大，那么 LRANGE 返回一个空列表。
     *  ·如果 stop 下标比 end 下标还要大，Redis将 stop 的值设置为 end
     * 如果 key 不是列表类型，返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String lrange(String[] arg) {
        if (checkArg(arg, 3)) {
            String res = String.valueOf(jedis.lrange(arg[0], Long.valueOf(arg[1]), Long.valueOf(arg[2])));
            logger.info("执行Redis命令：[lrange " + arg[0] + " " + arg[1] + " " + arg[2] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * rpush key value
     * 列表（List）命令 rpush，将一个 value 插入到列表 key 的表尾(最右边)
     * 下如果 key 不存在，一个空列表会被创建并执行 LPUSH 操作
     * 如果 key 不是列表类型，返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String rpush(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.rpush(arg[0], arg[1]));
            logger.info("执行Redis命令：[rpush " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * flushdb
     * 服务（Server）命令 flushdb，清空当前数据库中的所有 key，此命令从不失败，总是返回 OK
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String flushdb(String[] arg) {
        if (checkArg(arg, 0)) {
            String res = jedis.flushDB();
            logger.info("执行Redis命令：[flushDB]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * dbsize
     * 服务（Server）命令 dbsize，返回当前数据库的 key 的数量
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String dbsize(String[] arg) {
        if (checkArg(arg, 0)) {
            String res = String.valueOf(jedis.dbSize());
            logger.info("执行Redis命令：[dbSize]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * sadd key member
     * 集合（Set）命令 sadd，将一个 member 元素加入到集合 key 当中，已经存在于集合的 member 元素将被忽略
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String sadd(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.sadd(arg[0], arg[1]));
            logger.info("执行Redis命令：[sadd " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * scard key
     * 集合（Set）命令 scard，返回集合 key 的基数(集合中元素的数量)，当 key 不存在时，返回 0
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String scard(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.scard(arg[0]));
            logger.info("执行Redis命令：[scard " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * srandmember key count
     * 集合（Set）命令 srandmember
     * 如果 count 为正数，且小于集合基数，那么命令返回一个包含 count 个元素的数组，数组中的元素各不相同。如果 count 大于等于集合基数，那么返回整个集合。
     * 如果 count 为负数，那么命令返回一个数组，数组中的元素可能会重复出现多次，而数组的长度为 count 的绝对值
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String srandmember(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.srandmember(arg[0], Integer.valueOf(arg[1])));
            logger.info("执行Redis命令：[srandmember " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * smembers key
     * 集合（Set）命令 smembers，返回集合 key 中的所有成员，不存在的 key 被视为空集合
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String smembers(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.smembers(arg[0]));
            logger.info("执行Redis命令：[smembers " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * sismember key member
     * 集合（Set）命令 sismember，判断 member 元素是否集合 key 的成员
     * 如果 member 元素是集合的成员，返回 1
     * 如果 member 元素不是集合的成员，或 key 不存在，返回 0
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String sismember(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.sismember(arg[0], arg[1]));
            logger.info("执行Redis命令：[sismember " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * zadd key score member
     * 有序集合（SortedSet）命令 zadd，将一个 member 元素及其 score 值加入到有序集 key 当中
     * 如果某个 member 已经是有序集的成员，那么更新这个 member 的 score 值，并通过重新插入这个 member 元素，来保证该 member 在正确的位置上
     * score 值可以是整数值或双精度浮点数
     * 如果 key 不存在，则创建一个空的有序集并执行 ZADD 操作
     * 当 key 存在但不是有序集类型时，返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String zadd(String[] arg) {
        if (checkArg(arg, 3)) {
            String res = String.valueOf(jedis.zadd(arg[0], Double.valueOf(arg[1]), arg[2]));
            logger.info("执行Redis命令：[zadd " + arg[0] + " " + arg[1] + " " + arg[2] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * zcard key
     * 有序集合（SortedSet）命令 zcard，返回有序集 key 的基数
     * 当 key 存在且是有序集类型时，返回有序集的基数
     * 当 key 不存在时，返回 0
     * 当 key 存在但不是有序集类型时，返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String zcard(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.zcard(arg[0]));
            logger.info("执行Redis命令：[zcard " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * zcount key min max
     * 有序集合（SortedSet）命令 zcount，返回有序集 key 中， score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量
     * 当 key 存在但不是有序集类型时，返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String zcount(String[] arg) {
        if (checkArg(arg, 3)) {
            String res = String.valueOf(jedis.zcount(arg[0], Double.valueOf(arg[1]), Double.valueOf(arg[2])));
            logger.info("执行Redis命令：[zcount " + arg[0] + " " + arg[1] + " " + arg[2] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * zrange key start stop
     * 有序集合（SortedSet）命令 zrange，返回有序集 key 中，指定区间内的成员
     * 其中成员的位置按 score 值递增(从小到大)来排序，有相同 score 值的成员按字典序(lexicographical order )来排列
     * 下标参数 start 和 stop 都以 0 为底，也就是说，以 0 表示有序集第一个成员，以 1 表示有序集第二个成员，以此类推
     * 你也可以使用负数下标，以 -1 表示最后一个成员， -2 表示倒数第二个成员，以此类推
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String zrange(String[] arg) {
        if (checkArg(arg, 3)) {
            String res = String.valueOf(jedis.zrange(arg[0], Long.valueOf(arg[1]), Long.valueOf(arg[2])));
            logger.info("执行Redis命令：[zrange " + arg[0] + " " + arg[1] + " " + arg[2] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * zrangebyscore key min max
     * 有序集合（SortedSet）命令 zrangebyscore，返回有序集 key 中，所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员
     * 其中成员的位置按 score 值递增(从小到大)来排序，有相同 score 值的成员按字典序(lexicographical order )来排列
     * 下标参数 start 和 stop 都以 0 为底，也就是说，以 0 表示有序集第一个成员，以 1 表示有序集第二个成员，以此类推
     * 你也可以使用负数下标，以 -1 表示最后一个成员， -2 表示倒数第二个成员，以此类推
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String zrangebyscore(String[] arg) {
        if (checkArg(arg, 3)) {
            String res = String.valueOf(jedis.zrangeByScore(arg[0], arg[1], arg[2]));
            logger.info("执行Redis命令：[zrangeByScore " + arg[0] + " " + arg[1] + " " + arg[2] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * zrank key member
     * 有序集合（SortedSet）命令 zrank，返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列
     * 排名以 0 为底，也就是说， score 值最小的成员排名为 0
     * 如果 member 是有序集 key 的成员，返回 member 的排名
     * 如果 member 不是有序集 key 的成员，返回 nil
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String zrank(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.zrank(arg[0], arg[1]));
            logger.info("执行Redis命令：[zrank " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * zrevrange key start stop
     * 有序集合（SortedSet）命令 zrevrange，返回有序集 key 中，指定区间内的成员
     * 其中成员的位置按 score 值递减(从大到小)来排列，
     * 具有相同 score 值的成员按字典序的逆序(reverse lexicographical order)排列
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String zrevrange(String[] arg) {
        if (checkArg(arg, 3)) {
            String res = String.valueOf(jedis.zrevrange(arg[0], Long.valueOf(arg[1]), Long.valueOf(arg[2])));
            logger.info("执行Redis命令：[zrevrange " + arg[0] + " " + arg[1] + " " + arg[2] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * zrevrangebyscore key min max
     * 有序集合（SortedSet）命令 zrevrangebyscore，移除有序集 key 中，所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员
     * 返回被移除成员的数量
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String zrevrangebyscore(String[] arg) {
        if (checkArg(arg, 3)) {
            String res = String.valueOf(jedis.zrevrangeByScore(arg[0], arg[1], arg[2]));
            logger.info("执行Redis命令：[zrevrangeByScore " + arg[0] + " " + arg[1] + " " + arg[2] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * zrank key member
     * 有序集合（SortedSet）命令 zrank，返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)排序
     * 排名以 0 为底，也就是说， score 值最大的成员排名为 0
     * 如果 member 是有序集 key 的成员，返回 member 的排名
     * 如果 member 不是有序集 key 的成员，返回 nil
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String zrevrank(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.zrevrank(arg[0], arg[1]));
            logger.info("执行Redis命令：[zrevrank " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * zscore key member
     * 有序集合（SortedSet）命令 zscore，返回有序集 key 中，成员 member 的 score 值
     * 如果 member 元素不是有序集 key 的成员，或 key 不存在，返回 nil
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String zscore(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.zscore(arg[0], arg[1]));
            logger.info("执行Redis命令：[zscore " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * append key value
     * 字符串（String）命令 append
     * 如果 key 已经存在并且是一个字符串， APPEND 命令将 value 追加到 key 原来的值的末尾
     * 如果 key 不存在， APPEND 就简单地将给定 key 设为 value ，就像执行 SET key value 一样
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String append(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.append(arg[0], arg[1]));
            logger.info("执行Redis命令：[append " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * bitcount key
     * 字符串（String）命令 bitcount，计算给定字符串中，被设置为 1 的比特位的数量
     * 不存在的 key 被当成是空字符串来处理，因此对一个不存在的 key 进行 BITCOUNT 操作，结果为 0
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String bitcount(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.bitcount(arg[0]));
            logger.info("执行Redis命令：[bitcount " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * decr key
     * 字符串（String）命令 decr，将 key 中储存的数字值减一
     * 如果 key 不存在，那么 key 的值会先被初始化为 0 ，然后再执行 DECR 操作
     * 如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String decr(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.decr(arg[0]));
            logger.info("执行Redis命令：[decr " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * incr key
     * 字符串（String）命令 incr，将 key 中储存的数字值加一
     * 如果 key 不存在，那么 key 的值会先被初始化为 0 ，然后再执行 INCR 操作
     * 如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String incr(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.incr(arg[0]));
            logger.info("执行Redis命令：[incr " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * decrBy key decrement
     * 字符串（String）命令 decrBy，将 key 所储存的值减去减量 decrement
     * 如果 key 不存在，那么 key 的值会先被初始化为 0 ，然后再执行 DECRBY 操作
     * 如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String decrby(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.decrBy(arg[0], Long.valueOf(arg[1])));
            logger.info("执行Redis命令：[decrBy " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * incrBy key decrement
     * 字符串（String）命令 incrBy，将 key 所储存的值加上增量 increment
     * 如果 key 不存在，那么 key 的值会先被初始化为 0 ，然后再执行 INCRBY 操作
     * 如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String incrby(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.incrBy(arg[0], Long.valueOf(arg[1])));
            logger.info("执行Redis命令：[incrBy " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * get key
     * 字符串（String）命令 get，返回 key 所关联的字符串值
     * 如果 key 不存在那么返回特殊值 nil
     * 如果 key 不是字符串类型，那么返回一个错误，因为 GET 只能用于处理字符串值
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String get(String[] arg) {
        if (checkArg(arg, 1)) {
            String res = String.valueOf(jedis.get(arg[0]));
            logger.info("执行Redis命令：[get " + arg[0] + "]  结果：" + res);
            return res;
        }
        return null;
    }

    /**
     * set key value
     * 字符串（String）命令 set，将字符串值 value 关联到 key
     * 如果 key 已经持有其他值， SET 就覆写旧值，无视类型
     * 对于某个原本带有生存时间（TTL）的键来说， 当 SET 命令成功在这个键上执行时， 这个键原有的 TTL 将被清除
     * @param arg   命令参数
     * @return  结果字符串，入参异常返回 null
     */
    public String set(String[] arg) {
        if (checkArg(arg, 2)) {
            String res = String.valueOf(jedis.set(arg[0], arg[1]));
            logger.info("执行Redis命令：[set " + arg[0] + " " + arg[1] + "]  结果：" + res);
            return res;
        }
        return null;
    }
}
